package com.scs.application.core.export;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.scs.application.core.utils.*;
import com.scs.application.modules.upms.entity.DictData;
import com.scs.application.modules.upms.service.DictDataService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.*;

@Slf4j
@Service
public class ExportService {

    @Value("${res.real-path}")
    private String resPath;

    @Autowired
    private DictDataService dictDataService;


    /**
     * 导出数据
     */
    public String export(List exportData, ExportParamDto exportParams) throws Exception {
        List<ExportHeadDTO> exportHeadDTOList = new ArrayList<>();
        //表头列
        List<Object> fields = JSONArray.parseArray(exportParams.getFields());
        fields.forEach(field -> {
            ExportHeadDTO exportHeadDTO = new ExportHeadDTO();
            JSONObject jsonObject = (JSONObject) field;
            exportHeadDTO.setName(jsonObject.get("field").toString())
                    .setText(jsonObject.getString("title"))
                    .setDict(jsonObject.get("dict")+"")
                    .setDatePattern(jsonObject.get("datePattern")+"")
                    .setFlowId(jsonObject.get("flowId")+"");
            if (jsonObject.containsKey("isRequired")) {
                exportHeadDTO.setRequired(jsonObject.getBooleanValue("isRequired"));
            } else {
                exportHeadDTO.setRequired(false);
            }
            exportHeadDTOList.add(exportHeadDTO);
        });

        //表头列 第二行
        List<ExportHeadDTO> exportHeadDTOList2 = new ArrayList<>();
        List<Object> fields2 = JSONArray.parseArray(exportParams.getFields2());
        if (fields2 != null && fields2.size() > 0){
            fields2.forEach(field -> {
                ExportHeadDTO exportHeadDTO = new ExportHeadDTO();
                JSONObject jsonObject = (JSONObject) field;
                exportHeadDTO.setName(jsonObject.get("field").toString())
                        .setText(jsonObject.get("title").toString())
                        .setDict(jsonObject.get("dict")+"")
                        .setDatePattern(jsonObject.get("datePattern")+"")
                        .setFlowId(jsonObject.get("flowId")+"");
                exportHeadDTOList2.add(exportHeadDTO);
            });
        }

//        String sheetName = exportParams.getSheetName();
        String sheetName = "sheet1";
        String fileName = exportParams.getFilename();
        if (StringUtils.isEmpty(fileName)) {
            fileName = DateUtils.format(new Date(), "yyyyMMddHHmmss");
        }
        String fileNameAll = fileName + ".xls";
        String downloadPath = "download/" + fileNameAll;
        String tmpFilePath = resPath + downloadPath;
        FileUtils.mkdirs(resPath + "download");
        File tmpFile = new File(tmpFilePath);
        log.debug("tmpFilePath={}", tmpFilePath);

        HSSFWorkbook workbook = new HSSFWorkbook();
        //工作表
        HSSFSheet sheet = workbook.createSheet(sheetName);

        int rowNextNum = 0;
        HSSFRow row;
        HSSFCell cell;
        HSSFFont font;
        HSSFCellStyle cellStyle;
        HSSFRichTextString richTextString;
        //表头列
        if (exportParams.getIsHeader()) {
            row = sheet.createRow(rowNextNum);
            for (int i = 0; i < exportHeadDTOList.size(); i++) {
                ExportHeadDTO exportHeadDTO = exportHeadDTOList.get(i);
                cell = row.createCell(i);
                exportHeadDTO.setText(exportHeadDTO.getText().replaceAll("#","\r\n"));
                richTextString = new HSSFRichTextString(UtilCommon.getStr(exportHeadDTO.getText(), ""));
                cell.setCellValue(richTextString);

                font = workbook.createFont();
                //字体大小
                font.setFontHeightInPoints((short) 11);
                font.setBold(true);   //字体加粗

                if (exportHeadDTO.isRequired()) {
                    font.setColor(HSSFFont.COLOR_RED);
                }

                cellStyle = workbook.createCellStyle();
                //水平居中
                cellStyle.setAlignment(HorizontalAlignment.CENTER);
                cellStyle.setFont(font);
                cellStyle.setWrapText(true);

                cell.setCellStyle(cellStyle);

                if (exportHeadDTO.getText().indexOf("\n") != -1) { //包含换行的
                    String[] headArr = exportHeadDTO.getText().split("\n");
                    String headMax = "";
                    for(String head : headArr){
                        if (head.getBytes().length > headMax.getBytes().length) headMax =head;

                    }
                    //cell宽度
                    sheet.setColumnWidth(i, (int) (headMax.getBytes().length * 1.2d * 256 > 12 * 256 ? headMax.getBytes().length * 1.2d * 256 : 12 * 256));
                }else {
                    //cell宽度
                    sheet.setColumnWidth(i, (int) (UtilCommon.getStr(exportHeadDTO.getText(), "").getBytes().length * 1.2d * 256 > 12 * 256 ? UtilCommon.getStr(exportHeadDTO.getText(), "").getBytes().length * 1.2d * 256 : 12 * 256));
                }
            }
            rowNextNum++;

            //第二行表头
            if (exportHeadDTOList2 != null && exportHeadDTOList2.size() > 0) {
                row = sheet.createRow(rowNextNum);
                for (int i = 0; i < exportHeadDTOList2.size(); i++) {
                    ExportHeadDTO exportHeadDTO = exportHeadDTOList2.get(i);
                    cell = row.createCell(i);
                    richTextString = new HSSFRichTextString(UtilCommon.getStr(exportHeadDTO.getText(), ""));
                    cell.setCellValue(richTextString);

                    font = workbook.createFont();
                    //字体大小
                    font.setFontHeightInPoints((short) 9);
                    cellStyle = workbook.createCellStyle();
                    //水平居中
                    cellStyle.setAlignment(HorizontalAlignment.CENTER);
                    cellStyle.setFont(font);
                    cellStyle.setWrapText(true);
                    cell.setCellStyle(cellStyle);

                    if (exportHeadDTO.getText().indexOf("\n") != -1) { //包含换行的
                        String[] headArr = exportHeadDTO.getText().split("\n");
                        String headMax = "";
                        for(String head : headArr){
                            if (head.getBytes().length > headMax.getBytes().length) headMax =head;

                        }
                        //cell宽度
                        sheet.setColumnWidth(i, (int) (headMax.getBytes().length * 1.2d * 256 > 12 * 256 ? headMax.getBytes().length * 1.2d * 256 : 12 * 256));
                    }else {
                        //cell宽度
                        sheet.setColumnWidth(i, (int) (UtilCommon.getStr(exportHeadDTO.getText(), "").getBytes().length * 1.2d * 256 > 12 * 256 ? UtilCommon.getStr(exportHeadDTO.getText(), "").getBytes().length * 1.2d * 256 : 12 * 256));
                    }

                    sheet.setColumnWidth(i, (int) (sheet.getColumnWidth(i)*0.6));
                }
                rowNextNum++;
            }
        }

        try {
            List<DictData> dictDataList = dictDataService.list();
            //数据区域
            for (Object exportDataRow : exportData) {
                row = sheet.createRow(rowNextNum);
                for (int i = 0; i < exportHeadDTOList.size(); i++) {
                    ExportHeadDTO exportHeadDTO = exportHeadDTOList.get(i);
                    String fieldValue = getFieldValueByName(exportHeadDTO.getName(), exportDataRow);
                    if (StringUtils.isNotBlank(fieldValue)) {
                        if (StringUtils.isNotBlank(exportHeadDTO.getDatePattern()) || exportHeadDTO.getName().toLowerCase().indexOf("time") != -1) { //日期类型
                            if (StringUtils.isBlank(exportHeadDTO.getDatePattern())) exportHeadDTO.setDatePattern("yyyy-MM-dd HH:mm:ss");

                            String year = fieldValue.substring(0, 4);
                            try {
                                if (fieldValue.lastIndexOf(".0") != -1) {
                                    //包含毫秒的先替换，
                                    //2012-12-12 12:12:12.0
                                    fieldValue=fieldValue.substring(0,fieldValue.indexOf("."));
                                    fieldValue = DateUtils.formatToAnotherPattern(fieldValue,exportHeadDTO.getDatePattern(),exportHeadDTO.getDatePattern());
                                }  else if(UtilNum.isPureDigital(year)&&fieldValue.lastIndexOf("T") != -1){
                                    fieldValue = fieldValue.replaceAll("T", " ");
                                } else if(fieldValue.contains("CST")){
                                    fieldValue = fieldValue.split(" ")[0]+" "+fieldValue.split(" ")[1]+" "+fieldValue.split(" ")[2]+" "+fieldValue.split(" ")[5]+" "+fieldValue.split(" ")[3]+" GMT+0800";
                                    fieldValue = DateUtils.format(new Date(fieldValue), exportHeadDTO.getDatePattern());
                                }
                                else {
                                    fieldValue = DateUtils.format(new Date(fieldValue), exportHeadDTO.getDatePattern());
                                }
                            }catch (Exception e) {
                                log.error("export，日期转换失败:" ,e);
                            }
                        }else if (StringUtils.isNotBlank(exportHeadDTO.getDict())) { //字典类型
                            final String fieldIntValue = StringUtils.parseBoolToInt(fieldValue);
                            Optional<DictData> optionalDictData = dictDataList.stream().filter(dict -> dict.getDictTypeCode().equals(exportHeadDTO.getDict()) && dict.getValue().equals(fieldIntValue)).findFirst();
                            if (optionalDictData.isPresent()) {
                                fieldValue = optionalDictData.get().getLabel();
                            }
                        }
                    }
                    richTextString = new HSSFRichTextString(fieldValue);
                    row.createCell(i).setCellValue(richTextString);
                }
                rowNextNum++;
            }

            OutputStream os = new FileOutputStream(tmpFile);
            workbook.write(os);
            return downloadPath;
        } catch (IOException e) {
            log.error("操作失败，原因:" + e.getMessage());
            throw e;
        } catch (Exception ex) {
            log.error("操作失败，原因:" + ex.getMessage());
            throw ex;
        }
    }

    private String getFieldValueByName(String fieldName, Object o) throws Exception {
        Object value;
        if (o instanceof HashMap) { //是hashMap
            value = ((HashMap) o).get(fieldName);
        } else { //是实体类
            Method method = o.getClass().getMethod("get" + StringUtils.capitalize(fieldName), new Class[]{});
            value = method.invoke(o, new Object[]{});
        }
        return value == null ? "" : value.toString();
    }
}
